﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;

namespace SweetSQL.Data
{
    internal static class Dynamic
    {
        public static DynamicGet BuildGet(Type type, PropertyInfo property)
        {
            DynamicMethod getMethod = new DynamicMethod("DynamicGet", typeof(object), new Type[] { typeof(object) }, type, true);
            ILGenerator getIL = getMethod.GetILGenerator();
            getIL.Emit(OpCodes.Ldarg_0);
            getIL.Emit(OpCodes.Call, property.GetGetMethod(true));
            if (property.PropertyType.IsValueType)
            {
                getIL.Emit(OpCodes.Box, property.PropertyType);
            }
            getIL.Emit(OpCodes.Ret);
            return (DynamicGet)getMethod.CreateDelegate(typeof(DynamicGet));
        }

        public static DynamicSet BuildSet(Type type, PropertyInfo property)
        {
            DynamicMethod setMethod = new DynamicMethod("DynamicSet", typeof(void), new Type[] { typeof(object), typeof(object) }, type, true);
            ILGenerator setIL = setMethod.GetILGenerator();
            setIL.Emit(OpCodes.Ldarg_0);
            setIL.Emit(OpCodes.Ldarg_1);
            if (property.PropertyType.IsValueType)
            {
                setIL.Emit(OpCodes.Unbox_Any, property.PropertyType);
            }
            setIL.Emit(OpCodes.Call, property.GetSetMethod(true));
            setIL.Emit(OpCodes.Ret);
            return (DynamicSet)setMethod.CreateDelegate(typeof(DynamicSet));
        }
    }
}
